package tests;

import static org.junit.Assert.*;

import java.io.File;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.GregorianCalendar;

import junit.extensions.PrivilegedAccessor;
import org.junit.Test;

import utility.Constants;
import database.Database;
import database.SqlWrapper;
import database.Table;

public class DatabaseTest {

	private static void dropTables() throws Exception{

		final Connection con = SqlWrapper.connectToSQLite();
		con.setAutoCommit(false);

		final Table recordedSessionsTable = (Table) PrivilegedAccessor.getValue(Class.forName("database.Database"),"recordedSessionsTable");
		final Statement st = con.createStatement();
		st.execute(SqlWrapper.dropTable(recordedSessionsTable));
		final Table activitiesTable = (Table) PrivilegedAccessor.getValue(Class.forName("database.Database"),"activitiesTable");
		st.execute(SqlWrapper.dropTable(activitiesTable));
		final Table groupTable = (Table) PrivilegedAccessor.getValue(Class.forName("database.Database"),"groupTable");
		st.execute(SqlWrapper.dropTable(groupTable));
		
		con.commit();
		con.close();
	}
	
	@Test
	public void testImport(){
		Database.init();
		Database.importRecords(new File("recordedsessions.csv"), 10);
		try {
			dropTables();
		} catch (Exception e) {
			e.printStackTrace();
			fail();
		}
	}
	
	@Test
	public void testFirst(){		
		long firstMillis = 1243540842000l;
		Timestamp firstDate = new Timestamp(firstMillis);
		
		try {
			final Method m = Database.class.getDeclaredMethod("getLocalMillis", Timestamp.class);
			m.setAccessible(true);
			firstMillis = (Long) m.invoke(m, firstDate);
		} catch (Exception e) {
			e.printStackTrace();
			fail();
			
		}
		
		Database.init();
		final String activities[] = {"PP","OS","DSA","Sleep","Deutsch","Algebra", "Italian"};
		Database.addActivity(activities);
		Database.importRecords(new File("recordedsessions.csv"),10);
		java.util.Date a = Database.getFirstDate(1);
		Timestamp first = Database.getLastFirstDate(1);
		
		firstDate = new Timestamp(firstMillis);
		assertEquals(firstDate,a);
		firstDate.setNanos(0);
		first.setNanos(0);
		GregorianCalendar cal = new GregorianCalendar();
		cal.setTime(firstDate);
		cal.set(Calendar.SECOND, 0);
		GregorianCalendar cal1 = new GregorianCalendar();
		cal1.setTime(first);
		cal1.set(Calendar.SECOND, 0);
		assertEquals(cal,cal1);
		
		try {
			dropTables();
		} catch (Exception e) {
			e.printStackTrace();
			fail();
		}
	}
	
	@Test
	public void testAddActivities(){
		final String activities[] = {"DSA", "PP", "Algebra", "Deutsch", "Italian", "OS","Sleep", "All", "Maintenance"};
		Database.init();
		for (final String activity: activities)
			Database.addActivity(activity);
		try {
			dropTables();
		} catch (Exception e) {
			
			e.printStackTrace();
			fail();
		}
	}

	@Test
	public void testAddRawRecord(){		
		Database.init();
		final String activities[] = {"DSA", "PP", "Algebra", "Deutsch", "Italian", "OS","Sleep", "All", "Maintenance"};
		for (final String activity: activities) Database.addActivity(activity);
		Constants.updateActivitiesList();
		
		final int TRIALS = 10;
		for (int i=1; i < TRIALS; i++){
			final int activityId = Database.getActivityID(Constants.activities[i%(Constants.activities.length)]);
			Database.addRecordedSession(activityId);
			try {
				Thread.sleep(10000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			Database.modifyEndTimeOf(activityId, System.currentTimeMillis());
		}
		try {
			dropTables();
		} catch (Exception e) {
			fail();			
		}
	}
/*
	@Test
	public void testGetTotal(){
		Database.init();
		final String activities[] = {"DSA", "PP", "Algebra", "Deutsch", "Italian", "OS","Sleep", "All", "Maintenance"};
		for (final String activity: activities) Database.addActivity(activity);
		Constants.updateActivitiesList();
		
		for (int i = 0; i<activities.length; i++)
			assertTrue(Database.getTotal(activities[i]) >= 0);
		try {
			dropTables();
		} catch (Exception e) {
			fail();			
			e.printStackTrace();
		}
	}*/
}
